home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / jpsrc2.zip / JRDJFIF.C < prev    next >
C/C++ Source or Header  |  1991-12-12  |  19KB  |  735 lines

  1. /*
  2.  * jrdjfif.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to decode standard JPEG file headers/markers.
  9.  * This will handle baseline and JFIF-convention JPEG files.
  10.  *
  11.  * This module relies on the JGETC macro and the read_jpeg_data method (which
  12.  * is provided by the user interface) to read from the JPEG data stream.
  13.  * Therefore, this module is NOT dependent on any particular assumption about
  14.  * the data source.  This fact does not carry over to more complex JPEG file
  15.  * formats such as JPEG-in-TIFF; those format control modules may well need to
  16.  * assume stdio input.
  17.  *
  18.  * read_file_header assumes that reading begins at the JPEG SOI marker
  19.  * (although it will skip non-FF bytes looking for a JPEG marker).
  20.  * The user interface must position the data stream appropriately.
  21.  *
  22.  * These routines are invoked via the methods read_file_header,
  23.  * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
  24.  */
  25.  
  26. #include "jinclude.h"
  27.  
  28. #ifdef JFIF_SUPPORTED
  29.  
  30.  
  31. typedef enum {            /* JPEG marker codes */
  32.   M_SOF0  = 0xc0,
  33.   M_SOF1  = 0xc1,
  34.   M_SOF2  = 0xc2,
  35.   M_SOF3  = 0xc3,
  36.   
  37.   M_SOF5  = 0xc5,
  38.   M_SOF6  = 0xc6,
  39.   M_SOF7  = 0xc7,
  40.   
  41.   M_JPG   = 0xc8,
  42.   M_SOF9  = 0xc9,
  43.   M_SOF10 = 0xca,
  44.   M_SOF11 = 0xcb,
  45.   
  46.   M_SOF13 = 0xcd,
  47.   M_SOF14 = 0xce,
  48.   M_SOF15 = 0xcf,
  49.   
  50.   M_DHT   = 0xc4,
  51.   
  52.   M_DAC   = 0xcc,
  53.   
  54.   M_RST0  = 0xd0,
  55.   M_RST1  = 0xd1,
  56.   M_RST2  = 0xd2,
  57.   M_RST3  = 0xd3,
  58.   M_RST4  = 0xd4,
  59.   M_RST5  = 0xd5,
  60.   M_RST6  = 0xd6,
  61.   M_RST7  = 0xd7,
  62.   
  63.   M_SOI   = 0xd8,
  64.   M_EOI   = 0xd9,
  65.   M_SOS   = 0xda,
  66.   M_DQT   = 0xdb,
  67.   M_DNL   = 0xdc,
  68.   M_DRI   = 0xdd,
  69.   M_DHP   = 0xde,
  70.   M_EXP   = 0xdf,
  71.   
  72.   M_APP0  = 0xe0,
  73.   M_APP15 = 0xef,
  74.   
  75.   M_JPG0  = 0xf0,
  76.   M_JPG13 = 0xfd,
  77.   M_COM   = 0xfe,
  78.   
  79.   M_TEM   = 0x01,
  80.   
  81.   M_ERROR = 0x100
  82. } JPEG_MARKER;
  83.  
  84.  
  85. /*
  86.  * Reload the input buffer after it's been emptied, and return the next byte.
  87.  * This is exported for direct use by the entropy decoder.
  88.  * See the JGETC macro for calling conditions.
  89.  *
  90.  * For this header control module, read_jpeg_data is supplied by the
  91.  * user interface.  However, header formats that require random access
  92.  * to the input file would need to supply their own code.  This code is
  93.  * left here to indicate what is required.
  94.  */
  95.  
  96. #if 0                /* not needed in this module */
  97.  
  98. METHODDEF int
  99. read_jpeg_data (decompress_info_ptr cinfo)
  100. {
  101.   cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
  102.  
  103.   cinfo->bytes_in_buffer = (int) FREAD(cinfo->input_file,
  104.                        cinfo->next_input_byte,
  105.                        JPEG_BUF_SIZE);
  106.   
  107.   if (cinfo->bytes_in_buffer <= 0)
  108.     ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
  109.  
  110.   return JGETC(cinfo);
  111. }
  112.  
  113. #endif
  114.  
  115.  
  116. /*
  117.  * Routines to parse JPEG markers & save away the useful info.
  118.  */
  119.  
  120.  
  121. LOCAL INT32
  122. get_2bytes (decompress_info_ptr cinfo)
  123. /* Get a 2-byte unsigned integer (e.g., a marker parameter length field) */
  124. {
  125.   INT32 a;
  126.   
  127.   a = JGETC(cinfo);
  128.   return (a << 8) + JGETC(cinfo);
  129. }
  130.  
  131.  
  132. LOCAL void
  133. skip_variable (decompress_info_ptr cinfo, int code)
  134. /* Skip over an unknown or uninteresting variable-length marker */
  135. {
  136.   INT32 length;
  137.   
  138.   length = get_2bytes(cinfo);
  139.   
  140.   TRACEMS2(cinfo->emethods, 1,
  141.        "Skipping marker 0x%02x, length %u", code, (int) length);
  142.   
  143.   for (length -= 2; length > 0; length--)
  144.     (void) JGETC(cinfo);
  145. }
  146.  
  147.  
  148. LOCAL void
  149. get_dht (decompress_info_ptr cinfo)
  150. /* Process a DHT marker */
  151. {
  152.   INT32 length;
  153.   UINT8 bits[17];
  154.   UINT8 huffval[256];
  155.   int i, index, count;
  156.   HUFF_TBL **htblptr;
  157.   
  158.   length = get_2bytes(cinfo)-2;
  159.   
  160.   while (length > 0) {
  161.     index = JGETC(cinfo);
  162.  
  163.     TRACEMS1(cinfo->emethods, 1, "Define Huffman Table 0x%02x", index);
  164.       
  165.     bits[0] = 0;
  166.     count = 0;
  167.     for (i = 1; i <= 16; i++) {
  168.       bits[i] = (UINT8) JGETC(cinfo);
  169.       count += bits[i];
  170.     }
  171.  
  172.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  173.          bits[1], bits[2], bits[3], bits[4],
  174.          bits[5], bits[6], bits[7], bits[8]);
  175.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  176.          bits[9], bits[10], bits[11], bits[12],
  177.          bits[13], bits[14], bits[15], bits[16]);
  178.  
  179.     if (count > 256)
  180.       ERREXIT(cinfo->emethods, "Bogus DHT counts");
  181.  
  182.     for (i = 0; i < count; i++)
  183.       huffval[i] = (UINT8) JGETC(cinfo);
  184.  
  185.     length -= 1 + 16 + count;
  186.  
  187.     if (index & 0x10) {        /* AC table definition */
  188.       index -= 0x10;
  189.       htblptr = &cinfo->ac_huff_tbl_ptrs[index];
  190.     } else {            /* DC table definition */
  191.       htblptr = &cinfo->dc_huff_tbl_ptrs[index];
  192.     }
  193.  
  194.     if (index < 0 || index >= NUM_HUFF_TBLS)
  195.       ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
  196.  
  197.     if (*htblptr == NULL)
  198.       *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
  199.   
  200.     memcpy((void *) (*htblptr)->bits, (void *) bits,
  201.        SIZEOF((*htblptr)->bits));
  202.     memcpy((void *) (*htblptr)->huffval, (void *) huffval,
  203.        SIZEOF((*htblptr)->huffval));
  204.     }
  205. }
  206.  
  207.  
  208. LOCAL void
  209. get_dac (decompress_info_ptr cinfo)
  210. /* Process a DAC marker */
  211. {
  212.   INT32 length;
  213.   int index, val;
  214.  
  215.   length = get_2bytes(cinfo)-2;
  216.   
  217.   while (length > 0) {
  218.     index = JGETC(cinfo);
  219.     val = JGETC(cinfo);
  220.  
  221.     TRACEMS2(cinfo->emethods, 1,
  222.          "Define Arithmetic Table 0x%02x: 0x%02x", index, val);
  223.  
  224.     if (index < 0 || index >= (2*NUM_ARITH_TBLS))
  225.       ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
  226.  
  227.     if (index >= NUM_ARITH_TBLS) { /* define AC table */
  228.       cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
  229.     } else {            /* define DC table */
  230.       cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
  231.       cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
  232.       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
  233.     ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
  234.     }
  235.  
  236.     length -= 2;
  237.   }
  238. }
  239.  
  240.  
  241. LOCAL void
  242. get_dqt (decompress_info_ptr cinfo)
  243. /* Process a DQT marker */
  244. {
  245.   INT32 length;
  246.   int n, i, prec;
  247.   UINT16 tmp;
  248.   QUANT_TBL_PTR quant_ptr;
  249.   
  250.   length = get_2bytes(cinfo) - 2;
  251.   
  252.   while (length > 0) {
  253.     n = JGETC(cinfo);
  254.     prec = n >> 4;
  255.     n &= 0x0F;
  256.  
  257.     TRACEMS2(cinfo->emethods, 1,
  258.          "Define Quantization Table %d  precision %d", n, prec);
  259.  
  260.     if (n >= NUM_QUANT_TBLS)
  261.       ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
  262.       
  263.     if (cinfo->quant_tbl_ptrs[n] == NULL)
  264.       cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
  265.     (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
  266.     quant_ptr = cinfo->quant_tbl_ptrs[n];
  267.  
  268.     for (i = 0; i < DCTSIZE2; i++) {
  269.       tmp = JGETC(cinfo);
  270.       if (prec)
  271.     tmp = (tmp<<8) + JGETC(cinfo);
  272.       quant_ptr[i] = tmp;
  273.     }
  274.  
  275.     for (i = 0; i < DCTSIZE2; i += 8) {
  276.       TRACEMS8(cinfo->emethods, 2, "        %4d %4d %4d %4d %4d %4d %4d %4d",
  277.            quant_ptr[i  ], quant_ptr[i+1], quant_ptr[i+2], quant_ptr[i+3],
  278.            quant_ptr[i+4], quant_ptr[i+5], quant_ptr[i+6], quant_ptr[i+7]);
  279.     }
  280.  
  281.     length -= DCTSIZE2+1;
  282.     if (prec) length -= DCTSIZE2;
  283.   }
  284. }
  285.  
  286.  
  287. LOCAL void
  288. get_dri (decompress_info_ptr cinfo)
  289. /* Process a DRI marker */
  290. {
  291.   if (get_2bytes(cinfo) != 4)
  292.     ERREXIT(cinfo->emethods, "Bogus length in DRI");
  293.  
  294.   cinfo->restart_interval = (UINT16) get_2bytes(cinfo);
  295.  
  296.   TRACEMS1(cinfo->emethods, 1,
  297.        "Define Restart Interval %d", cinfo->restart_interval);
  298. }
  299.  
  300.  
  301. LOCAL void
  302. get_app0 (decompress_info_ptr cinfo)
  303. /* Process an APP0 marker */
  304. {
  305. #define JFIF_LEN 14
  306.   INT32 length;
  307.   UINT8 b[JFIF_LEN];
  308.   int buffp;
  309.  
  310.   length = get_2bytes(cinfo) - 2;
  311.  
  312.   /* See if a JFIF APP0 marker is present */
  313.  
  314.   if (length >= JFIF_LEN) {
  315.     for (buffp = 0; buffp < JFIF_LEN; buffp++)
  316.       b[buffp] = (UINT8) JGETC(cinfo);
  317.     length -= JFIF_LEN;
  318.  
  319.     if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) {
  320.       /* Found JFIF APP0 marker: check version */
  321.       /* Major version must be 1 */
  322.       if (b[5] != 1)
  323.     ERREXIT2(cinfo->emethods, "Unsupported JFIF revision number %d.%02d",
  324.          b[5], b[6]);
  325.       /* Minor version should be 0 or 1, but try to process anyway if newer */
  326.       if (b[6] != 0 && b[6] != 1)
  327.     TRACEMS2(cinfo->emethods, 0, "Warning: unknown JFIF revision number %d.%02d",
  328.          b[5], b[6]);
  329.       /* Save info */
  330.       cinfo->density_unit = b[7];
  331.       cinfo->X_density = (b[8] << 8) + b[9];
  332.       cinfo->Y_density = (b[10] << 8) + b[11];
  333.       /* Assume colorspace is YCbCr, unless UI has overridden me */
  334.       if (cinfo->jpeg_color_space == CS_UNKNOWN)
  335.     cinfo->jpeg_color_space = CS_YCbCr;
  336.       TRACEMS3(cinfo->emethods, 1, "JFIF APP0 marker, density %dx%d  %d",
  337.            cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
  338.     } else {
  339.       TRACEMS(cinfo->emethods, 1, "Unknown APP0 marker (not JFIF)");
  340.     }
  341.   } else {
  342.     TRACEMS1(cinfo->emethods, 1,
  343.          "Short APP0 marker, length %d", (int) length);
  344.   }
  345.  
  346.   while (length-- > 0)        /* skip any remaining data */
  347.     (void) JGETC(cinfo);
  348. }
  349.  
  350.  
  351. LOCAL void
  352. get_sof (decompress_info_ptr cinfo, int code)
  353. /* Process a SOFn marker */
  354. {
  355.   INT32 length;
  356.   short ci;
  357.   int c;
  358.   jpeg_component_info * compptr;
  359.   
  360.   length = get_2bytes(cinfo);
  361.   
  362.   cinfo->data_precision = JGETC(cinfo);
  363.   cinfo->image_height   = get_2bytes(cinfo);
  364.   cinfo->image_width    = get_2bytes(cinfo);
  365.   cinfo->num_components = JGETC(cinfo);
  366.  
  367.   TRACEMS4(cinfo->emethods, 1,
  368.        "Start Of Frame 0x%02x: width=%u, height=%u, components=%d",
  369.        code, (int) cinfo->image_width, (int) cinfo->image_height,
  370.        cinfo->num_components);
  371.  
  372.   /* We don't support files in which the image height is initially specified */
  373.   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
  374.   /* might as well have a general sanity check. */
  375.   if (cinfo->image_height <= 0 || cinfo->image_width <= 0
  376.       || cinfo->num_components <= 0)
  377.     ERREXIT(cinfo->emethods, "Empty JPEG image (DNL not supported)");
  378.  
  379. #ifdef EIGHT_BIT_SAMPLES
  380.   if (cinfo->data_precision != 8)
  381.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  382. #endif
  383. #ifdef TWELVE_BIT_SAMPLES
  384.   if (cinfo->data_precision != 12) /* this needs more thought?? */
  385.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  386. #endif
  387. #ifdef SIXTEEN_BIT_SAMPLES
  388.   if (cinfo->data_precision != 16) /* this needs more thought?? */
  389.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  390. #endif
  391.  
  392.   if (length != (cinfo->num_components * 3 + 8))
  393.     ERREXIT(cinfo->emethods, "Bogus SOF length");
  394.  
  395.   cinfo->comp_info = (jpeg_component_info *) (*cinfo->emethods->alloc_small)
  396.             (cinfo->num_components * SIZEOF(jpeg_component_info));
  397.   
  398.   for (ci = 0; ci < cinfo->num_components; ci++) {
  399.     compptr = &cinfo->comp_info[ci];
  400.     compptr->component_index = ci;
  401.     compptr->component_id = JGETC(cinfo);
  402.     c = JGETC(cinfo);
  403.     compptr->h_samp_factor = (c >> 4) & 15;
  404.     compptr->v_samp_factor = (c     ) & 15;
  405.     compptr->quant_tbl_no  = JGETC(cinfo);
  406.       
  407.     TRACEMS4(cinfo->emethods, 1, "    Component %d: %dhx%dv q=%d",
  408.          compptr->component_id, compptr->h_samp_factor,
  409.          compptr->v_samp_factor, compptr->quant_tbl_no);
  410.   }
  411. }
  412.  
  413.  
  414. LOCAL void
  415. get_sos (decompress_info_ptr cinfo)
  416. /* Process a SOS marker */
  417. {
  418.   INT32 length;
  419.   int i, ci, n, c, cc;
  420.   jpeg_component_info * compptr;
  421.   
  422.   length = get_2bytes(cinfo);
  423.   
  424.   n = JGETC(cinfo);  /* Number of components */
  425.   cinfo->comps_in_scan = n;
  426.   length -= 3;
  427.   
  428.   if (length != (n * 2 + 3) || n < 1 || n > MAX_COMPS_IN_SCAN)
  429.     ERREXIT(cinfo->emethods, "Bogus SOS length");
  430.  
  431.   TRACEMS1(cinfo->emethods, 1, "Start Of Scan: %d components", n);
  432.   
  433.   for (i = 0; i < n; i++) {
  434.     cc = JGETC(cinfo);
  435.     c = JGETC(cinfo);
  436.     length -= 2;
  437.     
  438.     for (ci = 0; ci < cinfo->num_components; ci++)
  439.       if (cc == cinfo->comp_info[ci].component_id)
  440.     break;
  441.     
  442.     if (ci >= cinfo->num_components)
  443.       ERREXIT(cinfo->emethods, "Invalid component number in SOS");
  444.     
  445.     compptr = &cinfo->comp_info[ci];
  446.     cinfo->cur_comp_info[i] = compptr;
  447.     compptr->dc_tbl_no = (c >> 4) & 15;
  448.     compptr->ac_tbl_no = (c     ) & 15;
  449.     
  450.     TRACEMS3(cinfo->emethods, 1, "    c%d: [dc=%d ac=%d]", cc,
  451.          compptr->dc_tbl_no, compptr->ac_tbl_no);
  452.   }
  453.   
  454.   while (length > 0) {
  455.     (void) JGETC(cinfo);
  456.     length--;
  457.   }
  458. }
  459.  
  460.  
  461. LOCAL void
  462. get_soi (decompress_info_ptr cinfo)
  463. /* Process an SOI marker */
  464. {
  465.   int i;
  466.   
  467.   TRACEMS(cinfo->emethods, 1, "Start of Image");
  468.  
  469.   /* Reset all parameters that are defined to be reset by SOI */
  470.  
  471.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  472.     cinfo->arith_dc_L[i] = 0;
  473.     cinfo->arith_dc_U[i] = 1;
  474.     cinfo->arith_ac_K[i] = 5;
  475.   }
  476.   cinfo->restart_interval = 0;
  477.  
  478.   cinfo->density_unit = 0;    /* set default JFIF APP0 values */
  479.   cinfo->X_density = 1;
  480.   cinfo->Y_density = 1;
  481.  
  482.   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling */
  483. }
  484.  
  485.  
  486. LOCAL int
  487. next_marker (decompress_info_ptr cinfo)
  488. /* Find the next JPEG marker */
  489. /* Note that the output might not be a valid marker code, */
  490. /* but it will never be 0 or FF */
  491. {
  492.   int c, nbytes;
  493.  
  494.   nbytes = 0;
  495.   do {
  496.     do {            /* skip any non-FF bytes */
  497.       nbytes++;
  498.       c = JGETC(cinfo);
  499.     } while (c != 0xFF);
  500.     do {            /* skip any duplicate FFs */
  501.       nbytes++;
  502.       c = JGETC(cinfo);
  503.     } while (c == 0xFF);
  504.   } while (c == 0);        /* repeat if it was a stuffed FF/00 */
  505.  
  506.   if (nbytes != 2)
  507.     TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before marker 0x%02x",
  508.          nbytes-2, c);
  509.  
  510.   return c;
  511. }
  512.  
  513.  
  514. LOCAL JPEG_MARKER
  515. process_tables (decompress_info_ptr cinfo)
  516. /* Scan and process JPEG markers that can appear in any order */
  517. /* Return when an SOI, EOI, SOFn, or SOS is found */
  518. {
  519.   int c;
  520.  
  521.   while (TRUE) {
  522.     c = next_marker(cinfo);
  523.       
  524.     switch (c) {
  525.     case M_SOF0:
  526.     case M_SOF1:
  527.     case M_SOF2:
  528.     case M_SOF3:
  529.     case M_SOF5:
  530.     case M_SOF6:
  531.     case M_SOF7:
  532.     case M_JPG:
  533.     case M_SOF9:
  534.     case M_SOF10:
  535.     case M_SOF11:
  536.     case M_SOF13:
  537.     case M_SOF14:
  538.     case M_SOF15:
  539.     case M_SOI:
  540.     case M_EOI:
  541.     case M_SOS:
  542.       return ((JPEG_MARKER) c);
  543.       
  544.     case M_DHT:
  545.       get_dht(cinfo);
  546.       break;
  547.       
  548.     case M_DAC:
  549.       get_dac(cinfo);
  550.       break;
  551.       
  552.     case M_DQT:
  553.       get_dqt(cinfo);
  554.       break;
  555.       
  556.     case M_DRI:
  557.       get_dri(cinfo);
  558.       break;
  559.       
  560.     case M_APP0:
  561.       get_app0(cinfo);
  562.       break;
  563.  
  564.     case M_RST0:        /* these are all parameterless */
  565.     case M_RST1:
  566.     case M_RST2:
  567.     case M_RST3:
  568.     case M_RST4:
  569.     case M_RST5:
  570.     case M_RST6:
  571.     case M_RST7:
  572.     case M_TEM:
  573.       TRACEMS1(cinfo->emethods, 1, "Unexpected marker 0x%02x", c);
  574.       break;
  575.  
  576.     default:    /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn */
  577.       skip_variable(cinfo, c);
  578.       break;
  579.     }
  580.   }
  581. }
  582.  
  583.  
  584.  
  585. /*
  586.  * Initialize and read the file header (everything through the SOF marker).
  587.  */
  588.  
  589. METHODDEF void
  590. read_file_header (decompress_info_ptr cinfo)
  591. {
  592.   int c;
  593.  
  594.   /* Expect an SOI marker first */
  595.   if (next_marker(cinfo) == M_SOI)
  596.     get_soi(cinfo);
  597.   else
  598.     ERREXIT(cinfo->emethods, "File does not start with JPEG SOI marker");
  599.  
  600.   /* Process markers until SOF */
  601.   c = process_tables(cinfo);
  602.  
  603.   switch (c) {
  604.   case M_SOF0:
  605.   case M_SOF1:
  606.     get_sof(cinfo, c);
  607.     cinfo->arith_code = FALSE;
  608.     break;
  609.       
  610.   case M_SOF9:
  611.     get_sof(cinfo, c);
  612.     cinfo->arith_code = TRUE;
  613.     break;
  614.  
  615.   default:
  616.     ERREXIT1(cinfo->emethods, "Unsupported SOF marker type 0x%02x", c);
  617.     break;
  618.   }
  619.  
  620.   /* Figure out what colorspace we have */
  621.   /* (too bad the JPEG committee didn't provide a real way to specify this) */
  622.  
  623.   switch (cinfo->num_components) {
  624.   case 1:
  625.     cinfo->jpeg_color_space = CS_GRAYSCALE;
  626.     break;
  627.  
  628.   case 3:
  629.     /* if we saw a JFIF marker, leave it set to YCbCr; */
  630.     /* also leave it alone if UI has provided a value */
  631.     if (cinfo->jpeg_color_space == CS_UNKNOWN) {
  632.       short cid0 = cinfo->comp_info[0].component_id;
  633.       short cid1 = cinfo->comp_info[1].component_id;
  634.       short cid2 = cinfo->comp_info[2].component_id;
  635.  
  636.       if (cid0 == 1 && cid1 == 2 && cid2 == 3)
  637.     cinfo->jpeg_color_space = CS_YCbCr; /* assume it's JFIF w/out marker */
  638.       else if (cid0 == 1 && cid1 == 4 && cid2 == 5)
  639.     cinfo->jpeg_color_space = CS_YIQ; /* prototype's YIQ matrix */
  640.       else {
  641.     TRACEMS3(cinfo->emethods, 0,
  642.          "Unrecognized component IDs %d %d %d, assuming YCbCr",
  643.          cid0, cid1, cid2);
  644.     cinfo->jpeg_color_space = CS_YCbCr;
  645.       }
  646.     }
  647.     break;
  648.  
  649.   case 4:
  650.     cinfo->jpeg_color_space = CS_CMYK;
  651.     break;
  652.  
  653.   default:
  654.     cinfo->jpeg_color_space = CS_UNKNOWN;
  655.     break;
  656.   }
  657. }
  658.  
  659.  
  660. /*
  661.  * Read the start of a scan (everything through the SOS marker).
  662.  * Return TRUE if find SOS, FALSE if find EOI.
  663.  */
  664.  
  665. METHODDEF boolean
  666. read_scan_header (decompress_info_ptr cinfo)
  667. {
  668.   int c;
  669.   
  670.   /* Process markers until SOS or EOI */
  671.   c = process_tables(cinfo);
  672.   
  673.   switch (c) {
  674.   case M_SOS:
  675.     get_sos(cinfo);
  676.     return TRUE;
  677.     
  678.   case M_EOI:
  679.     TRACEMS(cinfo->emethods, 1, "End Of Image");
  680.     return FALSE;
  681.  
  682.   default:
  683.     ERREXIT1(cinfo->emethods, "Unexpected marker 0x%02x", c);
  684.     break;
  685.   }
  686.   return FALSE;            /* keeps lint happy */
  687. }
  688.  
  689.  
  690. /*
  691.  * Finish up after a compressed scan (series of read_jpeg_data calls);
  692.  * prepare for another read_scan_header call.
  693.  */
  694.  
  695. METHODDEF void
  696. read_scan_trailer (decompress_info_ptr cinfo)
  697. {
  698.   /* no work needed */
  699. }
  700.  
  701.  
  702. /*
  703.  * Finish up at the end of the file.
  704.  */
  705.  
  706. METHODDEF void
  707. read_file_trailer (decompress_info_ptr cinfo)
  708. {
  709.   /* no work needed */
  710. }
  711.  
  712.  
  713. /*
  714.  * The method selection routine for standard JPEG header reading.
  715.  * Note that this must be called by the user interface before calling
  716.  * jpeg_decompress.  When a non-JFIF file is to be decompressed (TIFF,
  717.  * perhaps), the user interface must discover the file type and call
  718.  * the appropriate method selection routine.
  719.  */
  720.  
  721. GLOBAL void
  722. jselrjfif (decompress_info_ptr cinfo)
  723. {
  724.   cinfo->methods->read_file_header = read_file_header;
  725.   cinfo->methods->read_scan_header = read_scan_header;
  726.   /* For JFIF/raw-JPEG format, the user interface supplies read_jpeg_data. */
  727. #if 0
  728.   cinfo->methods->read_jpeg_data = read_jpeg_data;
  729. #endif
  730.   cinfo->methods->read_scan_trailer = read_scan_trailer;
  731.   cinfo->methods->read_file_trailer = read_file_trailer;
  732. }
  733.  
  734. #endif /* JFIF_SUPPORTED */
  735.